﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;
using System.IO;
using UlsStudio.AppCore;

namespace UlsStudio.DesktopApp
{
    public partial class SelectDatasourceForm : Form
    {
        #region Private & Constructors

        private string SIZE_LABEL_DIR_VALUE = string.Empty;
        private string SIZE_LABEL_ULS_DIR_VALUE = string.Empty;
        private string SIZE_LABEL_FILES_VALUE = string.Empty;

        public SelectDatasourceForm()
        {
            InitializeComponent();
            if (LastSelectedFiles == null) LastSelectedFiles = new List<FileInfo>();
        }
        #endregion

        #region Event Handlers

        #region Clicks

        private void btnOk_Click(object sender, EventArgs e)
        {
            // Build settings
            if (rbUlsLogs.Checked)
            {
                this.SelectedDirectory = new DirectoryInfo(Environment.ExpandEnvironmentVariables(txtUlsDir.Text));
                LastSelectedRadioButton = rbUlsLogs;
                if (this.SelectedDirectory.Exists == false)
                {
                    MessageBox.Show(string.Format("Directory '{0}' not found", this.SelectedDirectory.FullName), "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }
            }
            else if (rbDirectory.Checked)
            {
                this.SelectedDirectory = new DirectoryInfo(Environment.ExpandEnvironmentVariables(txtDirectory.Text));
                LastSelectedRadioButton = rbDirectory;
                if (this.SelectedDirectory.Exists == false)
                {
                    MessageBox.Show(string.Format("Directory '{0}' not found", this.SelectedDirectory.FullName), 
                        "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }
            }
            else if (rbFiles.Checked)
            {
                if (LastSelectedFiles == null || LastSelectedFiles.Count == 0)
                {
                    MessageBox.Show("Please select one or more files to load",
                        "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }
                this.FilesSelected = LastSelectedFiles;
                LastSelectedRadioButton = rbFiles;
            }

            // Save settings
            Properties.Settings.Default.LastLogDirectory = txtDirectory.Text;
            Properties.Settings.Default.Save();

            // Set form vars

            this.DialogResult = System.Windows.Forms.DialogResult.OK;

        }

        void btnDirectorySelect_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.SelectedPath = txtDirectory.Text;
            if (folderBrowserDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtDirectory.Text = folderBrowserDialog1.SelectedPath;
            }
        }

        private void btnSelectFiles_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                LastSelectedFiles.Clear();
                foreach (string selectedFile in openFileDialog1.FileNames)
                {
                    FileInfo inf = new FileInfo(selectedFile);
                    LastSelectedFiles.Add(inf);
                }

                // Size Label
                UpdateSelectedFileSizeLabel();
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void radioButtons_CheckedChanged(object sender, EventArgs e)
        {
            RadioButtonsChanged();
        }
        #endregion

        #region TextBoxen
        private void txtDirectory_TextChanged(object sender, EventArgs e)
        {
            // Update custom dir display
            long dirKb = GetDirectoryKbCount(new DirectoryInfo(txtDirectory.Text), true);
            lblDirectorySize.Text = string.Format(SIZE_LABEL_DIR_VALUE, dirKb);
        }

        private void txtUlsDir_TextChanged(object sender, EventArgs e)
        {
            if (rbUlsLogs.Enabled)
            {
                long size = 0;
                if (Directory.Exists(txtUlsDir.Text))
                {
                    size = GetDirectoryKbCount(new DirectoryInfo(txtUlsDir.Text), false);
                }
                lblUlsSize.Text = string.Format(SIZE_LABEL_ULS_DIR_VALUE, size);
            }
        }
        #endregion

        private void LoadDetails_Load(object sender, EventArgs e)
        {
            // Remember original labels text 
            if (string.IsNullOrEmpty(SIZE_LABEL_DIR_VALUE)) SIZE_LABEL_DIR_VALUE = lblDirectorySize.Text;
            if (string.IsNullOrEmpty(SIZE_LABEL_ULS_DIR_VALUE)) SIZE_LABEL_ULS_DIR_VALUE = lblDirectorySize.Text;
            if (string.IsNullOrEmpty(SIZE_LABEL_FILES_VALUE)) SIZE_LABEL_FILES_VALUE = lblDirectorySize.Text;

            // List of regitry keys to check for logging DIR
            string[] regKeys = 
            { 
                "SOFTWARE\\Microsoft\\Shared Tools\\Web Server Extensions\\14.0\\WSS", 
                "SOFTWARE\\Microsoft\\Shared Tools\\Web Server Extensions\\12.0\\WSS",
                "SOFTWARE\\Microsoft\\Shared Tools\\Web Server Extensions\\15.0\\WSS" 
            };

            // Process each version
            string logsDir = string.Empty; object logsRegObj = null;
            foreach (string regKey in regKeys)
            {
                // Is there a ULS logging folder?
                RegistryKey spkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regKey);
                if (spkey != null)
                {
                    logsRegObj = spkey.GetValue("LogDir");
                    if (logsRegObj != null) logsDir = logsRegObj.ToString();
                }
            }
            
            // ULS folder display
            if (string.IsNullOrEmpty(logsDir))
            {
                txtUlsDir.Text = "Not detected";
                lblUlsSize.Text = "n/a";
                rbUlsLogs.Enabled = false;
                if (LastSelectedRadioButton == null) rbDirectory.Checked = true;
            }
            else
            {
                logsDir = Environment.ExpandEnvironmentVariables(logsDir);
                txtUlsDir.Text = logsDir;
                rbUlsLogs.Enabled = true;
                if (LastSelectedRadioButton == null) rbUlsLogs.Checked = true; // Default to ULS if nothing selected before
            }

            // Load settings
            string startDir = Properties.Settings.Default.LastLogDirectory;
            if (string.IsNullOrEmpty(startDir) || !Directory.Exists(startDir))
            {
                startDir = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            }
            txtDirectory.Text = startDir;

            // Display mode
            if (this.FormMode == DatasourceSelectMode.DirectoriesOnly)
            {
                rbFiles.Enabled = false;
                pnlFiles.Enabled = false;
            }
            

            RadioButtonsChanged();
            UpdateSelectedFileSizeLabel();
        }

        #endregion

        #region Private Misc Methods
        /// <summary>
        /// Update logs KB estimate if necesary
        /// </summary>
        private long GetDirectoryKbCount(DirectoryInfo d, bool subFolders)
        {
            long size = 0;

            // Count size
            long logsBytes = 0;
            if (d.Exists)
            {
                foreach (System.IO.FileInfo logFile in d.GetFiles(UlsStudio.Engine.Constants.ULS_LOG_SEARCH_PATTERN))
                {
                    logsBytes += logFile.Length;
                }
            }

            // Update display
            size = logsBytes / 1024;


            return size;
        }

        private void RadioButtonsChanged()
        {
            pnlFiles.Enabled = false;
            pnlDir.Enabled = false;
            pnlUlsDir.Enabled = false;

            if (rbUlsLogs.Checked) pnlUlsDir.Enabled = true;
            else if (rbDirectory.Checked) pnlDir.Enabled = true;
            else if (rbFiles.Checked) pnlFiles.Enabled = true;
        }

        void UpdateSelectedFileSizeLabel()
        {
            string fileString = string.Empty; const string SEP = ", "; long fileSizes = 0;
            foreach (FileInfo inf in LastSelectedFiles)
            {
                fileString += inf.Name + SEP;
                fileSizes += inf.Length;
            }
            fileString = fileString.TrimEnd(SEP.ToCharArray());

            // Size Label
            txtFiles.Text = fileString;
            lblFileSize.Text = string.Format(SIZE_LABEL_FILES_VALUE, fileSizes / 1024);
        }

        #endregion

        #region Properties

        /// <summary>
        /// Individual files selected
        /// </summary>
        public static List<FileInfo> LastSelectedFiles { get; set; }

        /// <summary>
        /// Directory selected
        /// </summary>
        public DirectoryInfo SelectedDirectory { get; set; }

        /// <summary>
        /// Files selected
        /// </summary>
        public List<FileInfo> FilesSelected { get; set; }

        /// <summary>
        /// Last selected radio-button option since last load
        /// </summary>
        public static RadioButton LastSelectedRadioButton { get; set; }

        /// <summary>
        /// Select just dirs or files too?
        /// </summary>
        internal DatasourceSelectMode FormMode { get; set; }

        #endregion
                
    }
}
